package com.qianniu.napi.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.qianniu.napi.admin.entity.*;
import com.qianniu.napi.admin.entity.penum.*;
import com.qianniu.napi.admin.mapper.ChoujiangMapper;
import com.qianniu.napi.admin.service.*;
import com.qianniu.napi.common.config.Constants;
import com.qianniu.napi.common.util.DateUtil;
import com.qianniu.napi.common.util.ObjectUtil;
import com.qianniu.napi.common.util.StringUtil;
import org.redisson.api.RAtomicLong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author chenxuebin
 * @since 2018-12-14
 */
@Service
public class ChoujiangServiceImpl extends ServiceImpl<ChoujiangMapper, Choujiang> implements IChoujiangService {

    private static final Logger logger = LoggerFactory.getLogger(ChoujiangServiceImpl.class);
    @Autowired
    private IChoujiangLogService choujiangLogService;
    @Autowired
    private IRedisService redisService;
    @Autowired
    private IJifenService jifenService;
    @Autowired
    private IAccountService accountService;
    @Autowired
    private ICouponTplService couponTplService;
    @Autowired
    private IShareService shareService;
    @Autowired
    private IGoodsService goodsService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private ChoujiangMapper choujiangMapper;

    public int zhong(Long gid) {

        int jiangix = -1;
        Long uid = ObjectUtil.getUid();
        if (uid == null) {
            return jiangix;
        }
        if (gid == null || gid.longValue() <= 0) {
            return jiangix;
        }
        Goods goods = goodsService.selectById(gid);
        if (goods == null) {
            return jiangix;
        }
        Long mpid = ObjectUtil.getMpid();
        List<Choujiang> jplist = choujiangMapper.selectList(new EntityWrapper<Choujiang>()
                .eq("gid", gid)
                .eq("state", 1)
                .orderBy("level")
        );
        //1、用户抽奖次数判断
        //extkey1:单人每天可以抽多少次
        //extkey2:活动中奖率
        //extkey3:单人一次活动中最多中奖几次，默认1，一次活动中奖1次
        int daychou = goods.getExtkey1() == null ? 1 : Integer.parseInt(goods.getExtkey1());

        int todaychou = choujiangLogService.selectCount(new EntityWrapper<ChoujiangLog>()
                .eq("uid", uid).eq("gid", gid).eq("cjdate", DateUtil.getToday()));
        if (todaychou >= daychou) {
            return jiangix;
        }
        //2、用户该场活动总共中奖次数判断
        int zhongshu = goods.getExtkey3() == null ? 1 : Integer.parseInt(goods.getExtkey3());
        int haszhong = choujiangLogService.selectCount(new EntityWrapper<ChoujiangLog>()
                .eq("uid", uid).eq("gid", gid).eq("is_zhong", 1));
//                .eq("cjdate", DateUtil.getToday()));
        if (haszhong >= zhongshu) {
            return jiangix;
        }
        //3、计算中奖率，决定是否中奖
        double zjlv = goods.getExtkey2() == null ? 0.1 * 100 : Double.parseDouble(goods.getExtkey2()) * 100;//默认10%中奖率
        logger.info("------------------------00------------------------zjlv =" + zjlv);
        Random ram = new Random();
        int rs = ram.nextInt(100);
        logger.info("------------------------00------------------------rs =" + rs);
        if (rs >= zjlv) {
            return jiangix;
        }

        //计算头等奖+二等奖+三等奖+四等奖
        int maxnum1 = 0;//每日上限
        int maxnum2 = 0;
        int maxnum3 = 0;
        int maxnum4 = 0;

        int maxnumPday1 = 0;//每人上限
        int maxnumPday2 = 0;
        int maxnumPday3 = 0;
        int maxnumPday4 = 0;

        int leftnum1 = 0;//该奖剩余
        int leftnum2 = 0;
        int leftnum3 = 0;
        int leftnum4 = 0;

        Integer totalleft1 = 0;//每人剩余
        Integer totalleft2 = 0;
        Integer totalleft3 = 0;
        Integer totalleft4 = 0;

        int m = 0;
        for (Choujiang jiang : jplist) {
            logger.info("----------------------------------------------------jiang =" + JSON.toJSONString(jiang));

            if (jiang.getLevel() != null && jiang.getLevel() == 1) {
                maxnum1 = jiang.getMaxnum();
                maxnumPday1 = jiang.getMaxnumPday();
                leftnum1 = jiang.getMaxnumPday();
            } else if (jiang.getLevel() != null && jiang.getLevel() == 2) {
                maxnum2 = jiang.getMaxnum();
                maxnumPday2 = jiang.getMaxnumPday();
                leftnum2 = jiang.getMaxnumPday();
            } else if (jiang.getLevel() != null && jiang.getLevel() == 3) {
                maxnum3 = jiang.getMaxnum();
                maxnumPday3 = jiang.getMaxnumPday();
                leftnum3 = jiang.getMaxnumPday();
            } else if (jiang.getLevel() != null && jiang.getLevel() == 4) {
                maxnum4 = jiang.getMaxnum();
                maxnumPday4 = jiang.getMaxnumPday();
                leftnum4 = jiang.getMaxnumPday();
            }
            m++;
        }
        logger.info("--------------00------------------------leftnum1 =" + leftnum1);
        logger.info("--------------00------------------------leftnum2 =" + leftnum2);
        logger.info("--------------00------------------------leftnum3 =" + leftnum3);
        logger.info("--------------00------------------------leftnum4 =" + leftnum4);

        logger.info("--------------00------------------------maxnumPday1 =" + maxnumPday1);
        logger.info("--------------00------------------------maxnumPday2 =" + maxnumPday2);
        logger.info("--------------00------------------------maxnumPday3 =" + maxnumPday3);
        logger.info("--------------00------------------------maxnumPday4 =" + maxnumPday4);

        //缓存每种奖品今日出奖数
        String rskey1 = Constants.REDIS_JIANG1_NUM + "_" + gid + "_" + DateUtil.getToday("yyyyMMdd");
        String rskey2 = Constants.REDIS_JIANG2_NUM + "_" + gid + "_" + DateUtil.getToday("yyyyMMdd");
        String rskey3 = Constants.REDIS_JIANG3_NUM + "_" + gid + "_" + DateUtil.getToday("yyyyMMdd");
        String rskey4 = Constants.REDIS_JIANG4_NUM + "_" + gid + "_" + DateUtil.getToday("yyyyMMdd");

        RAtomicLong along1 = redisService.getRAtomicLong(rskey1);
        RAtomicLong along2 = redisService.getRAtomicLong(rskey2);
        RAtomicLong along3 = redisService.getRAtomicLong(rskey3);
        RAtomicLong along4 = redisService.getRAtomicLong(rskey4);

        if (along1 == null) redisService.set(rskey1, along1, 24, TimeUnit.HOURS);
        if (along2 == null) redisService.set(rskey1, along2, 24, TimeUnit.HOURS);
        if (along3 == null) redisService.set(rskey1, along3, 24, TimeUnit.HOURS);
        if (along4 == null) redisService.set(rskey1, along4, 24, TimeUnit.HOURS);

        if (along1 != null && along2.get() > 0) leftnum1 -= along1.get();
        if (along2 != null && along2.get() > 0) leftnum2 -= along2.get();
        if (along3 != null && along3.get() > 0) leftnum3 -= along3.get();
        if (along4 != null && along4.get() > 0) leftnum4 -= along4.get();

        logger.info("--------------------------------------num1Idx =" + along1.get());
        logger.info("--------------------------------------num2Idx =" + along2.get());
        logger.info("--------------------------------------num3Idx =" + along3.get());
        logger.info("--------------------------------------num4Idx =" + along4.get());

        logger.info("--------------------------------------maxnum1 =" + maxnum1);
        logger.info("--------------------------------------maxnum2 =" + maxnum2);
        logger.info("--------------------------------------maxnum3 =" + maxnum3);
        logger.info("--------------------------------------maxnum4 =" + maxnum4);

        logger.info("--------------11------------------------leftnum1 =" + leftnum1);
        logger.info("--------------11------------------------leftnum2 =" + leftnum2);
        logger.info("--------------11------------------------leftnum3 =" + leftnum3);
        logger.info("--------------11------------------------leftnum4 =" + leftnum4);

        Map<String, String> map = new HashMap<String, String>();
        map.put("cjdate", DateUtil.getToday());
        map.put("mpid", ObjectUtil.getMpid().toString());

        //当日中奖统计
        List<ChoujiangLog> list = choujiangLogService.getToujiangbygid(DateUtil.getToday(), gid.toString());
        for (ChoujiangLog cjlog : list) {
            if (cjlog.getLevel() == 1) {
                leftnum1 = maxnum1 - cjlog.getNum() >= maxnumPday1 ? maxnumPday1 : maxnum1 - cjlog.getNum(); //getNum 代表中奖总数
            } else if (cjlog.getLevel() == 2 && cjlog.getNum() == maxnum1) {
                leftnum2 = maxnum2 - cjlog.getNum() >= maxnumPday2 ? maxnumPday2 : maxnum2 - cjlog.getNum();//getNum 代表中奖总数
            } else if (cjlog.getLevel() == 3 && cjlog.getNum() == maxnum1) {
                leftnum3 = maxnum3 - cjlog.getNum() >= maxnumPday3 ? maxnumPday3 : maxnum3 - cjlog.getNum();//getNum 代表中奖总数
            } else if (cjlog.getLevel() == 4 && cjlog.getNum() == maxnum1) {
                leftnum4 = maxnum4 - cjlog.getNum() >= maxnumPday4 ? maxnumPday4 : maxnum4 - cjlog.getNum();//getNum 代表中奖总数
            }
        }
        logger.info("----------------22----------------------leftnum1 =" + leftnum1);
        logger.info("----------------22----------------------leftnum2 =" + leftnum2);
        logger.info("----------------22----------------------leftnum3 =" + leftnum3);
        logger.info("----------------22----------------------leftnum4 =" + leftnum4);

        //maxnumPday1>0才有效，不允许出现每人最高中0次
        //如果要出现每人最高中0次，则设置每日最高中奖数为0来达到该需求
        //我的中奖统计，1等奖几个，2等奖几个，3等奖几个，4等奖几个
        List<ChoujiangLog> mylist = choujiangLogService.getMyToujiangbygid(gid.toString());
        for (ChoujiangLog cjlog : mylist) {
            if (cjlog.getLevel() == 4) {
                if (leftnum4 > 0) leftnum4 = cjlog.getNum() == 0 ? leftnum4 : leftnum4 - cjlog.getNum();//getNum 代表中奖总数
            } else if (cjlog.getLevel() == 3) {
                if (leftnum3 > 0) leftnum3 = cjlog.getNum() == 0 ? leftnum3 : leftnum3 - cjlog.getNum();//getNum 代表中奖总数
            } else if (cjlog.getLevel() == 2) {
                if (leftnum2 > 0) leftnum2 = cjlog.getNum() == 0 ? leftnum2 : leftnum2 - cjlog.getNum();//getNum 代表中奖总数
            } else if (cjlog.getLevel() == 1) {
                if (leftnum1 > 0) leftnum1 = cjlog.getNum() == 0 ? leftnum1 : leftnum1 - cjlog.getNum();//getNum 代表中奖总数
            }
        }
        if (leftnum1 == 0 && leftnum2 == 0 && leftnum3 == 0 && leftnum4 == 0) {
            return jiangix;
        }

        int total = leftnum1 + leftnum2 + leftnum3 + leftnum4;
        logger.info("----------------2222----------------------leftnum1 =" + leftnum1);
        logger.info("----------------2222----------------------leftnum2 =" + leftnum2);
        logger.info("----------------2222----------------------leftnum3 =" + leftnum3);
        logger.info("----------------2222----------------------leftnum4 =" + leftnum4);
        logger.info("----------------2222----------------------total =" + total);
        List<Integer> jiangs = new ArrayList<Integer>();
        for (int i = 0; i < leftnum1; i++) {
            jiangs.add(0);
        }
        for (int i = 0; i < leftnum2; i++) {
            jiangs.add(1);
        }
        for (int i = 0; i < leftnum3; i++) {
            jiangs.add(2);
        }
        for (int i = 0; i < leftnum4; i++) {
            jiangs.add(3);
        }

        Random radm = new Random();
        int random = radm.nextInt(jiangs.size());
        random = jiangs.get(random);
        logger.info("------------------------------zhonglist random="+random);

        //随机数
        while (true) {
            if (random == 0) {
                if (leftnum1 == 0) {
                    logger.info("------------------------------zhonglist random==0");
                    random = (int) (1 + Math.random() * 10) % 4;
                } else {
                    along1.incrementAndGet();
                    break;
                }
            } else if (random == 1) {
                if (leftnum2 == 0) {
                    logger.info("------------------------------zhonglist random==1");
                    random = (int) (1 + Math.random() * 10) % 4;
                } else {
                    along1.incrementAndGet();
                    break;
                }
            } else if (random == 2) {
                if (leftnum3 == 0) {
                    logger.info("------------------------------zhonglist random==2");
                    random = (int) (1 + Math.random() * 10) % 4;
                } else {
                    along1.incrementAndGet();
                    break;
                }
            } else if (random == 3) {
                if (leftnum4 == 0) {
                    logger.info("------------------------------zhonglist random==3 ");
                    random = (int) (1 + Math.random() * 10) % 4;
                } else {
                    along1.incrementAndGet();
                    break;
                }
            } else {
                break;
            }
        }

        return random * 2;
    }

    public void lingjiang(ChoujiangLog choujiangLog) {

        Jinfo info = new Jinfo();
        Choujiang jiang = choujiangMapper.selectById(choujiangLog.getCjid());

//        ChoujiangLog choujiangLog = choujiangLogService.selectOne(new EntityWrapper<ChoujiangLog>()
//                .eq("uid", ObjectUtil.getUid())
//                .eq("islingqu", -1)
//                .eq("cjdate", DateUtil.getToday())
//        );
        if (choujiangLog.getIsZhong() == -1) {
            logger.debug("----------------------choujiangLog.getIsZhong() = " + choujiangLog.getIsZhong());
            return ;
        }
        User ruser = redisService.getUser();
        choujiangLog.setName(jiang.getName());
        choujiangLog.setPic(jiang.getPic());
        choujiangLog.setLevel(jiang.getLevel());
        choujiangLog.setJtype(jiang.getJtype());
        choujiangLog.setIslingqu(1);
        choujiangLog.setAvatarpic(ruser.getAvatarPic());
        choujiangLog.updateById();

        Long uid = ObjectUtil.getUid();
        Long mid = ObjectUtil.getMid();
        Long mpid = ObjectUtil.getMpid();
        Long oid = choujiangLog.getOid();
        Long gid = choujiangLog.getGid();

        //@1：积分；2：优惠券；3：商品；4：现金红包；5：谢谢参与
        if (jiang.getJtype() == 1) {
            JifenFlow jf = new JifenFlow();

            jf.setNum(new BigDecimal(jiang.getValue()));//充值金额（元）取整
            jf.setSn(StringUtil.getSnNo("J"));
            jf.setIsConfirm(1);
            jf.setState(1);
            jf.setIotype(IotypeEnum.input.getVal());//积分+
            jf.setJftype(JftypeEnum.zhongjiang.getVal());//积分返消费
            jf.setCreatetime(new Date());
            jf.setUid(uid);
            jf.setMid(mid);
            jf.setMpid(mpid);
            jf.setRemark("每日抽奖奖励积分");
            jf.insert();

            Jifen jifen = jifenService.selectOne(new EntityWrapper<Jifen>().eq("uid", uid));
            long version = jifen.getVersion();
            BigDecimal total = jifen.getTotal();
            Jifen njifen = new Jifen();

            njifen.setTotal(jf.getIotype() == 1 ? total.add(jf.getNum()) : total.subtract(jf.getNum()));
            njifen.setModifytime(new Date());
            njifen.setModifier(ObjectUtil.getUid());
            njifen.setVersion(version + 1);

            jifenService.update(njifen, new EntityWrapper<Jifen>().eq("uid", uid).eq("version", version));
        } else if (jiang.getJtype() == 2) {
            CouponTpl ctpl = couponTplService.selectById(jiang.getJid());
            //优惠券
            Coupon coupon = new Coupon();
            coupon.setIsUnused(1);//未使用
            coupon.setIsUsed(0);//已使用
            coupon.setIsForever(ctpl.getIsForever());//永久有效
            coupon.setIsOutdate(0);//已过期
            coupon.setState(1);

            coupon.setMid(mid);
            coupon.setMpid(mpid);
            coupon.setUid(uid);
            coupon.setSid(ctpl.getSid());
            coupon.setCreatetime(new Date());

            coupon.setTplid(jiang.getJid());
            coupon.setType(ctpl.getType());
            coupon.setName(ctpl.getName());
            coupon.setSlogo(ctpl.getSlogo());
            coupon.setSname(ctpl.getSname());
            coupon.setRemark(ctpl.getRemark());

            coupon.setCno(StringUtil.getQuanCode(mid));
            coupon.setSn(null);

            coupon.setStarttime(ctpl.getValidType() == 1 ? DateUtil.getToday() : ctpl.getStarttime());
            coupon.setEndtime(ctpl.getIsForever() == 1 ? null : ctpl.getValidType() == 1 ? DateUtil.addToday(ctpl.getExpire()) : ctpl.getEndtime());
            coupon.setCost(ctpl.getCost());
            coupon.setUsemin(ctpl.getUsemin());
            coupon.setOriginType(Qgettype.choujiang.getVal());//领券来源@1：领取；2：分享；3：赠送;4：充值;5：任务奖励;5：抽奖&
            //券核销了，应该触发关闭该活动订单状态

            coupon.insert();

            CouponTpl ctpl2 = new CouponTpl();
            ctpl2.setUse(ctpl.getUse() + 1);
            ctpl2.setId(ctpl.getId());
            ctpl2.updateById();

        } else if (jiang.getJtype() == 3) {
            //领取商品 ===待实现

        } else if (jiang.getJtype() == 4) {
            //虚拟币
            Boolean flag = false;
            Account naccount = new Account();
            BigDecimal zero = new BigDecimal(0);
            AccountFlow af = new AccountFlow();
            af.setRealpay(zero);
            af.setAmount(zero);
            af.setDikou(new BigDecimal(jiang.getValue()));
            af.setTotal(af.getRealpay().add(af.getAmount()).add(af.getDikou()));

            User user = redisService.getUser();
            af.setNickname(user != null ? user.getNickName() : null);
            af.setHeadimg(user != null ? user.getAvatarPic() : null);
            af.setPhone(user != null ? user.getPhone() : null);

            af.setUid(uid);
            af.setMid(mid);
            af.setMpid(mpid);
            af.setIsConfirm(-1);
            af.setState(1);

            af.setIotype(IotypeEnum.input.getVal());//1:入账
            af.setXftype(XftypeEnum.choujiang.getVal());//1:充值

            af.setCreatetime(new Date());
            af.setSn(StringUtil.getSnNo("J"));
            af.setRemark("每日抽奖");
            af.setTradetime(new Date());
            af.setCreatetime(new Date());

            while (af != null && !flag) {
                Account account = accountService.selectOne(new EntityWrapper<Account>().eq("uid", uid));
                if (account == null) {
                    logger.error(">>>account at uid=" + uid + " not exist and sn=" + af.getSn());
                    break;
                }

                Long version = account.getVersion();
                BigDecimal total = account.getTotal();
                BigDecimal mamount = account.getMamount();

                naccount.setTotal(total.add(af.getRealpay()).add(af.getDikou()));//getRealpay=实付+返现
                naccount.setMamount(mamount.add(af.getDikou()));

                naccount.setModifytime(new Date());
                naccount.setId(account.getId());
                naccount.setModifier(uid);
                naccount.setVersion(version + 1);

                af.setConfirmDate(new Date());
                af.setIsConfirm(1);//确认
                af.setLasttotal(account.getTotal());
                af.setLastamount(account.getAmount());
                flag = accountService.update(naccount, new EntityWrapper<Account>().eq("uid", uid).eq("version", version));
                if (flag) af.insert();
                logger.debug(">>>accountService.update flag=" + flag);
            }

            //摇奖红包属于营销金额，当产生交易时，商户端才会有变化
        }

        if (oid != null && oid > 0) {
            Order order = orderService.selectOne(new EntityWrapper<Order>()
                    .setSqlSelect("id,shipper_method shipperMethod").eq("id", oid));

            order.setId(oid);
            order.setStatus(StatusEnum.receving.getVal());
            //==待实现 更新是否发货
            //要求快递的话发货
            if (order.getShipperMethod() != null
                    && order.getShipperMethod() == 1) order.setFhstate(1);
            else order.setFhstate(2);
            //等核销完之后 更新状态

            order.setModifytime(new Date());
            order.setModifier(ObjectUtil.getUid());
            order.updateById();
        }

        if (gid != null && gid > 0) {

            Goods goods = goodsService.selectOne(new EntityWrapper<Goods>()
                    .setSqlSelect("id,ptotal,stores").eq("id", gid));
            goods.setId(gid);
            goods.setPtotal(goods.getPtotal() == null ? 1 : goods.getPtotal() + 1);//活动中奖人数
            goods.setStores(goods.getStores() - 1);//活动中奖人数

            if (goods.getStores() <= 0) {
                goods.setStatus(Gstatus.over.getVal());
            }
            goods.setModifytime(new Date());
            goods.setModifier(ObjectUtil.getUid());
            logger.debug("------------------lingjiang goods=" + JSON.toJSONString(goods));
            goods.updateById();

            //更新活动中奖商品
            Order order = orderService.selectOne(new EntityWrapper<Order>()
                    .setSqlSelect("id,goods_number goodsNumber")
                    .eq("gid", gid).eq("uid", ObjectUtil.getUid()));
            order.setGoodsNumber(order.getGoodsNumber() + 1);
            order.setStatus(StatusEnum.receving.getVal());
            order.updateById();
        }

        return ;
    }
}
